#pragma once

#include <iostream>
#include <memory>
#include <functional>

#include "Socket.hpp"
#include "InetAddr.hpp"
#include "Log.hpp"

using namespace socket_ns;

class TcpServer;

using http_t = std::function<std::string(std::string)>;

class ThreadData

{
public:
	ThreadData(socket_sptr fd, InetAddr addr, TcpServer *s) : sockfd(fd), clientaddr(addr), self(s)
	{
	}

public:
	socket_sptr sockfd;
	InetAddr clientaddr;
	TcpServer *self;
};

class TcpServer
{
public:
	TcpServer(uint16_t port, http_t service)
		: _localaddr("0", port),
		  _listensock(std::make_unique<TcpSocket>()),
		  _isrunning(false),
		  _http_service(service)
	{
		_listensock->BuildListenSocket(_localaddr);
	}

	static void *HandlerSock(void *args)
	{
		pthread_detach(pthread_self());
		ThreadData *td = static_cast<ThreadData *>(args);
		std::string request,response;

		//有较大概率读到一个完整的http request
		ssize_t n = td->sockfd->Recv(&request);
		if(n > 0)
		{
			response = td->self->_http_service(request);	//回调出去处理后再回来
			td->sockfd->Send(response);
		}

		td->sockfd->Close();
		delete td;
		return nullptr;
	}

	void Loop()
	{
		_isrunning = true;
		while (_isrunning)
		{
			InetAddr peeraddr;
			socket_sptr normalsock = _listensock->Accepter(&peeraddr);
			if (normalsock == nullptr)
				continue;

			pthread_t t;
			ThreadData *td = new ThreadData(normalsock, peeraddr, this);
			pthread_create(&t, nullptr, HandlerSock, td); // 将线程分离
		}

		_isrunning = false;
	}
	~TcpServer()
	{
	}

private:
	InetAddr _localaddr;
	std::unique_ptr<Socket> _listensock;
	bool _isrunning;

	http_t _http_service; 	// 外面传入的处理
};